#include <assert.h>
#include <ctype.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "array.h"
#include "util.h"
#include "mus.h"
#include "stat.h"

   /* Introduction. The \title{} project aims to solve the problem of
   identifying differences in the translocations related to the AID
   enzyme.

   The collected data were obtained from the sequencing of mouse genome
   with repair mechanism and AID acting altered. The problem is
   identifying how these properties affect the translocation of gene
       fragments.
  */

/* Data. The data is supposed to be located at current directory.  All
files are in {\tt bed} format and there are four of them to be
handled:

1. cMyc\_53BP1mm\_AIDmm.translocations: gene 53BP1 with repair and AID off (mm);
2. cMyc\_53BP1mm\_AIDrv.translocations: gene 53BP1 with repair off (mm) and 
    AID over-expressed (rv);
3. cMyc\_AIDmm.translocations: only AID off (mm);
4. cMyc\_AIDrv.translocations : AID over-expressed (rv).

The enumeration |AID_NSTATES| maps these combinations, the first two
characters represents the repair and the other two the AID. There are
three states:

- mm: off;
- xx: on;
- rv: over-expressed.

					  */
    enum aid_state {mmmm, mmrv, xxmm, xxrv, wrong_state};
#define AID_NSTATES (wrong_state-mmmm)


  enum aid_state get_state_id(char*dbfn)
{
    const unsigned short gsd_buflen=32;
 
  if (strncmp(dbfn, "cMyc_53BP1mm_AIDmm", gsd_buflen)==0)
    return mmmm;
  else if (strncmp(dbfn, "cMyc_53BP1mm_AIDrv", gsd_buflen)==0)
    return mmrv;
  else if (strncmp(dbfn, "cMyc_AIDmm", gsd_buflen)==0)
    return xxmm;
  else if (strncmp(dbfn, "cMyc_AIDrv", gsd_buflen)==0)
    return xxrv;
 
  return wrong_state;
 }

#define BUFLEN 256
char line[BUFLEN];
unsigned long long lno;


  struct chromosome {
    unsigned long long nbps; /* number of base pairs */
	   struct array*translocs[AID_NSTATES];
	   };

	 static struct chromosome mus_genome[MUS_NCHROMOSOMES];


  extern struct chromosome *bootstrap_mus_genome();
extern void shutdown_mus_genome(void);



    /* Files in ``bed'' format store genomic data from genes and
    chromosomes. The columns contains information about the break as
    follows:
    ------------------------------------------------------------
    | Column number | Description                               |
    ------------------------------------------------------------
    | 1             | Chromosome identification                 |
    | 2             | Break point location                      |
    | 3             | Break point location plus one             |
    | 4             | Primer information                        |
    | 5             | Number of reads with the same break point |
    | 6             | Read/sequence strand                      |
    | 7             | Same information of the column 2          |
    | 8             | Same information of the column 3          |
    | 9             | Used by genome browser                    |
    ------------------------------------------------------------

    An example of a file entry:
chr1 13053018 13053019 left_000647 5 - 13053018 13053019 77,175,74
				     */

/* Translocations. Data files containing information about not only chromosome
translocations but others that are not of interest are parsed and the breaks
are written into a binary file with a fixed structure.

The data containing only the breaks has the following structure:


1. Data set header structure with the information about the
  chromosome number, state combination applied to chromosome and
  number of breaks per chromosome that follows the header;

2. The breaks that might be read according to information written in
  the data set header.  
    */

enum aid_state get_state_id(char*dataset_base_filenname);

    static char *dataset_fns[AID_NSTATES] = {
    [mmmm]="cMyc_53BP1mm_AIDmm.translocations", 
    [mmrv]="cMyc_53BP1mm_AIDrv.translocations", 
    [xxmm]="cMyc_AIDmm.translocations", 
    [xxrv]="cMyc_AIDrv.translocations"
};
    inline char *aid_state_filename(const enum aid_state);

inline char *aid_state_filename(state)
      const enum aid_state state;
{
  return dataset_fns[state];
}


static void usage(char*prog); 


					  int main(int argc, char**argv)
				     {
		       unsigned char help=0;
		       enum aid_state i;


  bootstrap_mus_genome();

  for (i=0; i<AID_NSTATES; i++) {
		struct array *ary = mus_genome[0].translocs[i];

    stat_delta(ary, mus_genome[0].nbps);				     
				     
  }
  shutdown_mus_genome();
      
   if (help)
    usage(argv[0]);
      
  return help;
  }

static void usage(char*prog) 
{
  fprintf(stderr, "\nUsage: %s [-0 | -1 | -2]\n", prog);
  fprintf(stderr, "where:\n");
  fprintf(stderr, "\t-0\t Phase 0: Separate the breaks uniquely and write into \"aid.dat\";\n");
  fprintf(stderr, "\t-1\t Phase 1: Encode breaks using LZ algoritm;\n");
  fprintf(stderr, "\t-2\t Phase 2: Calculate the entropy of encoded data.\n");
  fprintf(stderr, "\n\tObs: Files containing translocations must be at the current \
directory to be processed.\n");
  printf("\n");
  exit(-1);
}

  struct chromosome *bootstrap_mus_genome()
{
	 enum mus_chromosome_index i;
  enum aid_state j;
  char *fn;
  FILE *fp;
    char *delim = " \t\r";
char *str, *tok, *saveptr, *end;
unsigned short tt=0;
enum mus_chromosome_index chrid;
unsigned long long transloc, prev_transloc=0;

  for (i=0; i<MUS_NCHROMOSOMES; i++) {
							mus_genome[i].nbps = get_mus_chromosome_nbps(i);
    for (j=0; j<AID_NSTATES; j++)
      mus_genome[i].translocs[j] = array_new(0, sizeof(unsigned long long));
  }

  for (i=0; i<AID_NSTATES; i++) {
    fn = aid_state_filename(i);
    fp = fopen(fn, "r");
    if (!fp)
							die ("Could not open %s.", fn);
    
							/* Filter translocations according to chromosomes */
							lno=0;
							next_line:
							while(fgets(line, BUFLEN, fp)!=NULL) {
    lno++;
							if (lno==1)
							continue;
    
							/* Tokenize line spliting chomosome number and translocation*/
							for (tt=0, str=line; ; tt++, str=NULL) {
    tok = strtok_r(str, delim, &saveptr);
    if (tt==2 || tok==NULL)
      break;
  
    if (tt==0)
      chrid = get_mus_chromosome_index(tok);
    else if (tt==1)
      transloc = strtoull(tok, &end, 10);
  }

if (prev_transloc == transloc)
  goto next_line;

prev_transloc = transloc;

array_push(mus_genome[chrid].translocs[i], (void *)&transloc);


  }
    
    fclose(fp);
  }
  
  return &mus_genome[0];
}


	 
							void shutdown_mus_genome(void)
{
							enum mus_chromosome_index i;
  enum aid_state j;

  for (i=0; i<MUS_NCHROMOSOMES; i++) {
    mus_genome[i].nbps = 0;
    for (j=0; j<AID_NSTATES; j++)
      array_free(mus_genome[i].translocs[j]);
  }
}



